--[[
    @Author       : baidwwy
    @Date         : 2021-02-08 15:51:46
    @LastEditTime : 2021-05-06 12:49:29
--]]
io.stdout:setvbuf('no',0)
gge = package.loadlib("ggelua", "luaopen_ggelua")()
local lfs = require("lfs")

local runpath = gge.getrunpath()--引擎目录
local curpath = arg[1]--gge.getcurpath()--项目目录

print(runpath,curpath)
package.path = package.path..';.\\.vscode\\?.lua'

--转换到绝对路径
local function 绝对路径(path)
    path = path:gsub('\\','/')
    if path:sub(1,2)=='./' then--项目目录
        path = path:gsub('.',curpath,1)
        return (path:gsub('/','\\')),curpath..'\\'
    else
        path = runpath..'/'..path
    end
    return (path:gsub('/','\\')),runpath..'/'
end

local function 分割文本(str, mark)
    if str  then
        local r = {}
        if mark == '%' then
            mark = "([^"..mark.."%]+)"
        else
            mark = "([^"..mark.."]+)"
        end

        for match in tostring(str):gmatch(mark) do
            table.insert(r,match)
        end
        return r
    end
    return {}
end

--处理sep和大小写
local function 处理路径(path)
    path = path:lower()--小写
    path = path:gsub('\\','/')
    return path
end

function 创建目录(path,...)
    if select("#", ...)>0 then
        path = path:format(...)
    end
    local dirsep = package.config:sub(1,1)
    if dirsep=='\\' then--windows
        path = path:gsub('/',dirsep)
    else
        path = path:gsub('\\',dirsep)
    end
    path = 分割文本(path,dirsep)
    if #path>1 then
        table.remove(path)
    end
    for i,v in ipairs(path) do
        lfs.mkdir(table.concat(path, dirsep,1,i))
    end
end

function 读取文件(path)
    local file<close> = io.open(path, 'rb');
    if file then
        return file:read('a')
    end
end

function 写出文件(path,data)
    local file<close> = io.open(path,"wb")
    if file then
        file:write(data)
        return true
    end
    return false
end

function 复制文件(old,new)
    old,new = 绝对路径(old),绝对路径(new)
    创建目录(new)
    local rf<close> = io.open(old,"rb")
    if rf then
        local wf<close> = io.open(new,"wb")
        if wf then
            wf:write(rf:read("a"))
            return true
        end
    end
    return false
end

function 遍历目录(path)
    local dir,u = lfs.dir(path)
    local pt = {}
    return function ()
        repeat
            local file = dir(u)
            if file then
                local f = path..'/'..file
                local attr = lfs.attributes (f)
                if attr and attr.mode == "directory" then
                    if file ~= "." and file ~= ".." then
                        table.insert(pt, f)
                    end
                    file = "."
                else
                    return f
                end
            elseif pt[1] then
                path = table.remove(pt, 1)
                dir,u = lfs.dir(path)
                file = "."
            end
        until file ~= "."
    end
end

--lfs.link(a,b,true)需要管理权限
function 联接目录(a,b)
    a,b = 绝对路径(a),绝对路径(b)
    创建目录(b)
    os.execute(string.format('mklink /j "%s" "%s"',b,a))
end

function 联接文件(a,b)
    a,b = 绝对路径(a),绝对路径(b)
    创建目录(b)
    os.execute(string.format('mklink /h "%s" "%s"',b,a))
end
--把资源打包到sqlite
function 打包目录(path,file,psd)
    path,file = 绝对路径(path),绝对路径(file)
    local env = setmetatable({arg={arg[1],path,file,psd}},{__index=_G});
    
    loadfile(runpath.."\\tools\\torespack.lua","bt",env)()
end


--启动脚本
local script,core = {}
do
    local r = assert(读取文件(runpath.."/ggelua.lua"), '读取失败:ggelua.lua')
    local fun = assert(load(r,"ggelua.lua"))
    core = string.dump(fun)
end

function 编译目录(path,strip)
    path,dir = 绝对路径(path)
    for path in 遍历目录(path) do
        path = 处理路径(path)
        if path:sub(-3)=='lua' then
            local r = assert(读取文件(path), '读取失败:'..path)
            path = path:sub(#dir+1)--删除绝对路径
            local fun = assert(load(r,path))
            script[path] = string.dump(fun,strip)
            print('dump -> '..path)
        end
    end
end

function 编译文件(path,strip)
    path = 绝对路径(path)
end

local function getscript()
    local data,path = {},{}
    for k,v in pairs(script) do
        table.insert(path, k)
        table.insert(data, v)
    end
    local head = "GGEP"..string.pack("<I4I4",#path,0)
    local list,offset = {},12+#path*string.packsize("<c256I4I4I4")
    for i,v in ipairs(path) do
        table.insert(list,string.pack("<c256I4I4I4",v,gge.hash(v),offset,#data[i]))
        offset=offset+#data[i]
    end
    data = head..table.concat(list)..table.concat(data)
    return data
end

function 写出Windows(path,c)
    复制文件(c and "GGELUAc.exe" or "GGELUA.exe",path)
    path = 绝对路径(path)
    创建目录(path)
    
    local file<close> = io.open(path,"r+b")

    if file then
        if file:seek('end',-12) then
            local glue = file:read(12)
            local data = getscript()
            if glue and #glue==12 then
                local sig,s1,s2 = string.unpack("<I4I4I4",glue)
                if sig==0x20454747 then
                    file:seek('end',-(12+s1+s2))
                end
                file:seek('cur')--没有这句，会有奇怪的数据
                file:write(core)
                file:write(data)
                file:write(string.pack("<I4I4I4",0x20454747,#core,#data))
                return true
            end
        end
    end
    error("写出失败",2)
    return false
end

function 写出Android(path)
    path = 绝对路径(path)
    --创建目录(path)
    --创建目录('android')
    local file<close> = io.open("ggescript","wb")
    if file then
        local data = getscript()
        file:write(core)
        file:write(data)
        file:write(string.pack("<I4I4I4",0x20454747,#core,#data))
        return
    end
    error("写出失败",2)
    return false
end

function 写出脚本()
    -- local file<close> = io.open("ggescript","wb")
    -- if file then
    --     local data = getscript()
    --     file:write(core)
    --     file:write(data)
    --     file:write(string.pack("<I4I4I4",0x20454747,#core,#data))
    -- end
end
print(require("ggebuild"))
--os.execute('explorer '..curpath)